<!-- subpkg_consult/room/index.vue -->
<script lang="ts" setup>
import { useUserStore } from '@/stores/user'
import io from 'socket.io-client'
import type { Socket } from 'socket.io-client'
import { orderDetailApi } from '@/apis/consult'

import roomStatus from './components/room-status.vue'
import patientInfo from './components/patient-info.vue'
import notifyInfo from './components/notify-info.vue'
import messageInfo from './components/message-info.vue'
import prescriptionInfo from './components/prescription-info.vue'
import type { OrderDetail } from '@/types/consult'
import { ref } from 'vue'
import type { MsgData, MsgItem } from '@/types/room'
import { uploadImgApi } from '@/apis/consult'
import { nextTick } from 'vue'
// 1. 接收路由参数（支付宝支付完成，放弃，携带给我们的参数）
// orderId=7050656273821696&payResult=true&type=2
const props = defineProps<{
  orderId: string
  payResult: string
}>()

if (props.payResult === 'false') {
  // 支付失败，返回我的页面不再继续聊天
  uni.switchTab({
    url: '/pages/my/index',
  })
}


// 2. 建立连接
const store = useUserStore()
const socket: Socket = io('https://consult-api.itheima.net', {
  auth: { token: 'Bearer ' + store.token },
  query: { orderId: props.orderId },
  transports: ['websocket', 'polling'],
  timeout: 5000,
})

socket.on('connect', () => {
  // 建立连接成功
  console.log('连接建立成功')
})

socket.on('error', event => {
  // 错误异常消息
  console.log('出现错误')
})

socket.on('disconnect', () => {
  // 已经断开连接
  console.log('断开连接')
})

// 3. 获取订单信息 并传递给 状态组件
const orderInfo = ref({} as OrderDetail)
const getOrderInfo = async () => {
  const res = await orderDetailApi(props.orderId)
  console.log(res)
  orderInfo.value = res
}
getOrderInfo()

// 4. 获取历史信息
// 消息列表
const messageList = ref<MsgItem[]>([])
// 获取历史消息
socket.on('chatMsgList', (res: MsgData) => {
  // 没有返回数据
  if (res.code !== 10000) return
  // console.log('历史消息：', res.data)
  // 提取列表数据
  res.data?.forEach(({ items, createTime }) => {
    // 追加到消息列表中 展开运算符
    // 合并当前这一个数组时，额外的增加一个分隔符即可
    // push方法支持传入多个元素，目前的写法，每次添加之前，额外的 push 一个元素
    messageList.value.push({
      msgType: 31,
      msg: { content: createTime },
      id: Date.now().toString(),
    })
    messageList.value.push(...items!)
  })
  console.log('历史消息：', messageList.value)
})


// 5.接收服务器主动发过来的信息
socket.on('receiveChatMsg', (message: MsgItem) => {
  // 修改消息为已读
  socket.emit('updateMsgStatus', message.id)
  // 接收到的消息追加到消息列表中
  messageList.value.push(message)
  // console.log(messageList.value)

  // 只要有信息，就滚到 id 对应的位置
  // vue数据更新是异步，数据变更-》ui 变更
  // 滚动列表需要等待 ui 更新完毕再执行
  // nextTick 中写的回调函数，会在 ui更新完毕之后执行，再去滚动界面就没有问题了
  nextTick(() => {
    sp.value = 'item' + (messageList.value.length - 1)
  })
})

// 监听订单状态改变-执行回调函数
socket.on('statusChange', () => {
  // console.log('订单状态改变')
  // 重新获取订单信息，刷新状态-页面更新了
  getOrderInfo()
})




// 6. 给服务器发消息
const iptMessage = ref('')
const onConfirm = () => {
  if (iptMessage.value == '') return
  // console.log(iptMessage.value)
  socket.emit('sendChatMsg', {
    // 当前的用户 id,登录的时候把用户 id 保存到了仓库中
    from: store.userId,
    // 医生 id 订单信息中
    to: orderInfo.value.docInfo.id,
    // 信息的类型
    msgType: 1,
    // 信息的内容
    msg: {
      content: iptMessage.value,
    },
  })

  iptMessage.value = ''
}




// 7.发送图片消息
const sendImageMessage = async () => {
  if (orderInfo.value.status !== 3) {
    return uni.showToast({
      title: '医生还没接诊，别着急哦',
    })
  }
  const res = await uni.chooseImage()
  // console.log(res)
  const picture = await uploadImgApi(res.tempFilePaths[0])
  // console.log(picture)
  socket.emit('sendChatMsg', {
    // 当前的用户 id,登录的时候把用户 id 保存到了仓库中
    from: store.userId,
    // 医生 id 订单信息中
    to: orderInfo.value.docInfo.id,
    // 信息的类型
    msgType: 4, // 图片信息
    // 信息的内容
    msg: {
      // content: iptMessage.value,
      picture, // 发送图片需要传递 picture 对象
    },
  })
}

// 8. 控制滚动
const sp = ref('')
</script>

<template>
  <view class="room-page">
    <!-- 订单的状态 -->
    <roomStatus :status="orderInfo.status" :statusValue="orderInfo.statusValue" :countdown="orderInfo.countdown" />
    <scroll-view :scroll-into-view="sp" refresher-enabled refresher-background="#f2f2f2" scroll-y style="flex: 1; overflow: hidden">
      <!-- view 会 id 属性， item0-----累加 itemn -->
      <view class="message-container" v-for="(item, i) in messageList" :key="item.id" :id="'item' + i">
        <!-- 此处将来填充更多代码... -->
        <!-- <template > -->
        <!-- 患者的信息 -->
        <patientInfo v-if="item.msgType == 21" :info="item.msg?.consultRecord!" />
        <!-- 类型 31 ,32 ,33 渲染 提示信息 -->
        <notifyInfo v-if="item.msgType!>=31" :type="item.msgType">
          <!-- 传递给 默认插槽 -->
          {{ item.msg?.content }}
        </notifyInfo>

        <!-- 服务器推送过来的图文信息 -->
        <messageInfo v-if="item.msgType!<=4" :info="item" :type="item.msgType!" />

        <!-- 处方信息 -->
        <prescriptionInfo v-if="item.msgType === 22" :info="item.msg?.prescription!" />
        <!-- </template> -->
      </view>
    </scroll-view>

    <!-- 发送消息 -->
    <view class="message-bar">
      <template v-if="true">
       <!-- 如果医生没有接诊，无法给医生发消息的 
          disabled=true 禁用输入框
          disabled=false 启用输入框
          status=3 医生已经接诊 disabled 跟的应该是 false
        -->
        <uni-easyinput
          v-model="iptMessage"
          @confirm="onConfirm"
          :disabled="orderInfo.status != 3"
          :clearable="false"
          :input-border="false"
          placeholder-style="font-size: 32rpx; color: #c3c3c5;"
          placeholder="问医生"
        />
        <view @click="sendImageMessage" class="image-button">
          <uni-icons size="40" color="#979797" type="image"></uni-icons>
        </view>
      </template>
      <button v-else class="uni-button">咨询其它医生</button>
    </view>
  </view>
</template>

<style lang="scss">
@import './index.scss';
</style>